/*
 * MediaSinkArray.h
 *
 *  Created on: 2015年12月31日
 *      Author: terry
 */

#ifndef MEDIASINKARRAY_H_
#define MEDIASINKARRAY_H_

#include "MediaStream.h"
#include <deque>
#include "TCriticalSection.h"
#include <algorithm>


namespace av
{


class MediaSinkArray
{
public:
	MediaSinkArray()
	{

	}

	~MediaSinkArray()
	{
		removeSinks();
	}

	size_t size()
	{
    	comn::AutoCritSec lock(m_cs);
		return m_sinks.size();
	}

	int addSink(MediaSinkPtr pSink)
	{
		if (!pSink)
		{
			return EINVAL;
		}

		if (exists(pSink))
		{
			return EEXIST;
		}

		comn::AutoCritSec lock(m_cs);
		m_sinks.push_back(pSink);
		return 0;
	}

	bool removeSink(MediaSinkPtr pSink)
	{
		bool found = false;
    	comn::AutoCritSec lock(m_cs);
		MediaSinkDeque::iterator it = find(pSink);
		if (it != m_sinks.end())
		{
			m_sinks.erase(it);
			found = true;
		}
		return found;
	}

	void removeSinks()
	{
    	comn::AutoCritSec lock(m_cs);
    	m_sinks.clear();
	}

	size_t getSinkCount()
	{
    	comn::AutoCritSec lock(m_cs);
		return m_sinks.size();
	}

	bool exists(MediaSinkPtr sink)
	{
    	comn::AutoCritSec lock(m_cs);
		MediaSinkDeque::iterator it = find(sink);
		return (it != m_sinks.end());
	}

    void fireMediaFormat(const MediaFormat& fmt)
    {
    	comn::AutoCritSec lock(m_cs);
		for (size_t i = 0; i < m_sinks.size(); ++ i)
		{
			m_sinks[i]->onMediaFormat(fmt);
		}
    }

    void fireMediaPacket(MediaPacketPtr& pkt)
    {
    	comn::AutoCritSec lock(m_cs);
		for (size_t i = 0; i < m_sinks.size(); ++ i)
		{
			m_sinks[i]->onMediaPacket(pkt);
		}
    }

    void fireMediaEvent(int event)
    {
    	comn::AutoCritSec lock(m_cs);
    	for (size_t i = 0; i < m_sinks.size(); ++ i)
    	{
    		m_sinks[i]->onMediaEvent(event);
    	}
    }

protected:
    typedef std::deque< MediaSinkPtr >		MediaSinkDeque;

    MediaSinkDeque::iterator find(MediaSinkPtr sink)
    {
    	return std::find(m_sinks.begin(), m_sinks.end(), sink);
    }

protected:

    MediaSinkDeque	m_sinks;
    comn::CriticalSection m_cs;

};



}


#endif /* MEDIASINKARRAY_H_ */
